#ifndef _PG_REGEX_H_
#define _PG_REGEX_H_			/* 再也不想经历一次 */
/*
 * regular expressions
 *
 * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
 *
 * Development of this software was funded, in part, by Cray Research Inc.,
 * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
 * Corporation, none of whom are responsible for the results.  The author
 * thanks all of them.
 *
 * Redistribution and use in source and binary forms -- with or without
 * modification -- are permitted for any purpose, provided that
 * redistributions in source form retain this entire copyright notice and
 * indicate the origin and nature of any modifications.
 *
 * I'd appreciate being given credit for this package in the documentation
 * of software which uses it, but that is not a requirement.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * src/include/regex/regex.h
 */

/*
 * 这是一个 POSIX regex_t 的实现，因此它与系统提供的 
 * <regex.h> 头文件存在冲突。该头文件可能已经被
 * 无意中包含，因此我们在所有系统上强制加载它，以展示
 * 我们能够兼容并且完全替代系统的正则表达式接口。
 *
 * 请注意，我们避免使用 _REGEX_H_ 作为包含保护，因为
 * 这会混淆 BSD 家族系统（包括 macOS）使用相同的包含保护
 * 的情况。
 */
#ifndef _WIN32
#include <regex.h>
#endif

/* 避免由于系统头文件造成的重新定义错误。 */
#undef REG_UBACKREF
#undef REG_ULOOKAROUND
#undef REG_UBOUNDS
#undef REG_UBRACES
#undef REG_UBSALNUM
#undef REG_UPBOTCH
#undef REG_UBBS
#undef REG_UNONPOSIX
#undef REG_UUNSPEC
#undef REG_UUNPORT
#undef REG_ULOCALE
#undef REG_UEMPTYMATCH
#undef REG_UIMPOSSIBLE
#undef REG_USHORTEST
#undef REG_BASIC
#undef REG_EXTENDED
#undef REG_ADVF
#undef REG_ADVANCED
#undef REG_QUOTE
#undef REG_NOSPEC
#undef REG_ICASE
#undef REG_NOSUB
#undef REG_EXPANDED
#undef REG_NLSTOP
#undef REG_NLANCH
#undef REG_NEWLINE
#undef REG_PEND
#undef REG_EXPECT
#undef REG_BOSONLY
#undef REG_DUMP
#undef REG_FAKE
#undef REG_PROGRESS
#undef REG_NOTBOL
#undef REG_NOTEOL
#undef REG_STARTEND
#undef REG_FTRACE
#undef REG_MTRACE
#undef REG_SMALL
#undef REG_OKAY
#undef REG_NOMATCH
#undef REG_BADPAT
#undef REG_ECOLLATE
#undef REG_ECTYPE
#undef REG_EESCAPE
#undef REG_ESUBREG
#undef REG_EBRACK
#undef REG_EPAREN
#undef REG_EBRACE
#undef REG_BADBR
#undef REG_ERANGE
#undef REG_ESPACE
#undef REG_BADRPT
#undef REG_ASSERT
#undef REG_INVARG
#undef REG_MIXED
#undef REG_BADOPT
#undef REG_ETOOBIG
#undef REG_ECOLORS
#undef REG_ATOI
#undef REG_ITOA
#undef REG_PREFIX
#undef REG_EXACT

/*
 * 如有需要，可以在此添加您自己的定义。
 */
#include "mb/pg_wchar.h"

/*
 * 接口类型等。
 */

/*
 * regoff_t 必须足够大以容纳 either off_t 或 ssize_t，
 * 并且必须是有符号的；长整型是否合适仅仅是一个猜测。
 */
typedef long pg_regoff_t;

/*
 * 其他接口类型
 */

/* 重要，编译后的正则表达式（或者说，它的前端） */
typedef struct
{
	int			re_magic;		/* 魔法数字 */
	size_t		re_nsub;		/* 子表达式的数量 */
	long		re_info;		/* 以下标志的位掩码: */
#define  REG_UBACKREF		000001	/* 有反向引用 (\n) */
#define  REG_ULOOKAROUND	000002	/* 有前瞻/后顾约束 */
#define  REG_UBOUNDS		000004	/* 有有界量词 ({m,n}) */
#define  REG_UBRACES		000010	/* 有不以量词开始的 { */
#define  REG_UBSALNUM		000020	/* 有在非 ARE 中的反斜杠字母数字 */
#define  REG_UPBOTCH		000040	/* 在 ERE 中有不匹配的右括号（合法
									 * 按照规范，但这是真正的错误） */
#define  REG_UBBS			000100	/* 在括号表达式中有反斜杠 */
#define  REG_UNONPOSIX		000200	/* 有任何扩展 POSIX 的构造 */
#define  REG_UUNSPEC		000400	/* 有任何 POSIX 禁止的情况，例如
									 * 一个空分支 */
#define  REG_UUNPORT		001000	/* 有数字字符代码依赖 */
#define  REG_ULOCALE		002000	/* 有地区依赖 */
#define  REG_UEMPTYMATCH	004000	/* 可以匹配零长度字符串 */
#define  REG_UIMPOSSIBLE	010000	/* 可以证明不能匹配任何内容 */
#define  REG_USHORTEST		020000	/* 有非贪婪量词 */
	int			re_csize;		/* sizeof(character) */
	char	   *re_endp;		/* 向后兼容的临时解决方案 */
	Oid			re_collation;	/* 定义 LC_CTYPE 行为的排序 */
	/* 剩下的是指向隐藏内部的模糊指针 */
	char	   *re_guts;		/* `char *` 比 `void *` 更具可移植性 */
	char	   *re_fns;
} pg_regex_t;

/* 结果报告（可能会获取更多字段） */
typedef struct
{
	pg_regoff_t rm_so;			/* 子字符串的开始 */
	pg_regoff_t rm_eo;			/* 子字符串的结束 */
} pg_regmatch_t;

/* 补充控制和报告 */
typedef struct
{
	pg_regmatch_t rm_extend;	/* 参见 REG_EXPECT */
} rm_detail_t;



/*
 * 正则表达式编译标志
 */
#define REG_BASIC	000000		/* BRE（便利） */
#define REG_EXTENDED	000001	/* EREs */
#define REG_ADVF	000002		/* ERE中的高级特性 */
#define REG_ADVANCED	000003	/* ARE（也是ERE） */
#define REG_QUOTE	000004		/* 无特殊字符，绝无 */
#define REG_NOSPEC	REG_QUOTE	/* 历史同义词 */
#define REG_ICASE	000010		/* 忽略大小写 */
#define REG_NOSUB	000020		/* 调用者不需要子表达式匹配数据 */
#define REG_EXPANDED	000040	/* 扩展格式，空格和注释 */
#define REG_NLSTOP	000100		/* \n不匹配.或[^ ] */
#define REG_NLANCH	000200		/* ^在\n之后匹配，$在之前 */
#define REG_NEWLINE 000300		/* 换行符是行终止符 */
#define REG_PEND	000400		/* 唉——向后兼容性黑客 */
#define REG_EXPECT	001000		/* 报告部分/有限匹配的细节 */
#define REG_BOSONLY 002000		/* 针对仅BOS匹配的临时权宜之计 */
#define REG_DUMP	004000		/* 不关你的事 :-) */
#define REG_FAKE	010000		/* 不关你的事 :-) */
#define REG_PROGRESS	020000	/* 不关你的事 :-) */



/*
 * 正则表达式执行标志
 */
#define REG_NOTBOL	0001		/* BOS不是BOL */
#define REG_NOTEOL	0002		/* EOS不是EOL */
#define REG_STARTEND	0004	/* 向后兼容的临时解决方案 */
#define REG_FTRACE	0010		/* 与你无关 */
#define REG_MTRACE	0020		/* 与你无关 */
#define REG_SMALL	0040		/* 与你无关 */


/*
 * 错误报告
 * 如果修改错误代码列表，请小心 -- regerror() 使用的表
 * 是从此文件自动生成的！
 */
#define REG_OKAY	 0			/* 未检测到错误 */
#define REG_NOMATCH  1			/* 匹配失败 */
#define REG_BADPAT	 2			/* 无效的正则表达式 */
#define REG_ECOLLATE	 3		/* 无效的排序元素 */
#define REG_ECTYPE	 4			/* 无效的字符类 */
#define REG_EESCAPE  5			/* 无效的转义 \ 序列 */
#define REG_ESUBREG  6			/* 无效的回溯引用编号 */
#define REG_EBRACK	 7			/* 方括号 [] 不平衡 */
#define REG_EPAREN	 8			/* 括号 () 不平衡 */
#define REG_EBRACE	 9			/* 花括号 {} 不平衡 */
#define REG_BADBR	10			/* 无效的重复计数 */
#define REG_ERANGE	11			/* 无效的字符范围 */
#define REG_ESPACE	12			/* 内存不足 */
#define REG_BADRPT	13			/* 量词操作数无效 */
#define REG_ASSERT	15			/* "不可能发生" -- 你发现了一个错误 */
#define REG_INVARG	16			/* regex 函数的无效参数 */
#define REG_MIXED	17			/* regex 和字符串的字符宽度不同 */
#define REG_BADOPT	18			/* 无效的嵌入选项 */
#define REG_ETOOBIG 19			/* 正则表达式过于复杂 */
#define REG_ECOLORS 20			/* 颜色过多 */
#define REG_CANCEL	21			/* 操作已取消 */
/* 用于调试和测试的两个特殊 */
#define REG_ATOI	101			/* 将错误代码名称转换为编号 */
#define REG_ITOA	102			/* 将错误代码编号转换为名称 */
/* pg_regprefix 的非错误结果代码 */
#define REG_PREFIX	(-1)		/* 确定了一个公共前缀 */
#define REG_EXACT	(-2)		/* 确定了一个精确匹配 */


/* 将标准类型名称重定向到我们的类型名称。 */
#define regoff_t pg_regoff_t
#define regex_t pg_regex_t
#define regmatch_t pg_regmatch_t


/*
 * 导出的函数的原型
 */

/* regcomp.c */
extern int	pg_regcomp(regex_t *, const pg_wchar *, size_t, int, Oid);
extern int	pg_regexec(regex_t *, const pg_wchar *, size_t, size_t, rm_detail_t *, size_t, regmatch_t[], int);
extern int	pg_regprefix(regex_t *, pg_wchar **, size_t *);
extern void pg_regfree(regex_t *);
extern size_t pg_regerror(int, const regex_t *, char *, size_t);

/* regexp.c */
extern regex_t *RE_compile_and_cache(text *text_re, int cflags, Oid collation);
extern bool RE_compile_and_execute(text *text_re, char *dat, int dat_len,
								   int cflags, Oid collation,
								   int nmatch, regmatch_t *pmatch);

#endif							/* _PG_REGEX_H_ */
